home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 176-200 / 179 / unixutil / alloc.c next >
C/C++ Source or Header  |  1995-03-13  |  3KB  |  123 lines

  1. /* alloc.c - memory allocator
  2.  *
  3.  * The point of this is that it is about 4 times faster than MANX malloc/free
  4.  * in c.lib.  Malloc in heapmem.o will not allocate a second heap if the first
  5.  * is exhausted.
  6.  * :ts=8
  7.  */
  8.  
  9.  
  10. #define NULL        0L
  11. #define HOWMUCH        4096L    /* how much memory to AllocMem() at a time */
  12.  
  13. typedef struct header {
  14.       struct header *next;    /* next block */
  15.       unsigned long size;    /* block size */
  16. };
  17.  
  18. struct header first;
  19.  
  20. struct header *head = NULL;    /* start of list */
  21.  
  22.  
  23. char *alloc (bytes)
  24. unsigned bytes;
  25. {
  26.    struct header *getmem ();
  27.    register struct header *p, *q;
  28.    register long size;
  29.  
  30.    size = (((bytes + 2 * sizeof (struct header) - 1) >> 3) << 3);
  31.    if ((q = head) == NULL) {
  32.       first.next = head = q = &first;
  33.       first.size = 0L;
  34.    }
  35.    for (p = q->next; ; q = p, p = p->next) {
  36.       if (p->size >= size) {    /* if this block is large enough */
  37.          if (p->size == size)
  38.         q ->next = p->next;
  39.      else {        /* remove memory from tail of block */
  40.         p->size -= size;
  41.         p = (struct header *) ((char *) p + p->size);
  42.            p->size = size;
  43.      }
  44.      head = q;
  45.      p->next = NULL;
  46.      return ((char *) (p+1));
  47.       }
  48.       if (p == head)    /* back where we started */
  49.      if ((p = getmem ()) == NULL)
  50.         return (NULL);    /* cannot allocate memory */
  51.    }
  52. }
  53.  
  54.  
  55. /* freeit - put block back in free list */
  56.  
  57. freeit (ptr)
  58. char *ptr;
  59. {
  60.    register struct header *p, *q;
  61.  
  62.    p = (struct header *) ptr - 1;
  63.    for (q = head; ; q = q->next) {
  64.       if (p > q && p < q->next)
  65.      break;        /* new block goes between q & q->next */
  66.       if (q >= q->next && p > q)
  67.      break;        /* new block goes at end of list */
  68.       if (q >= q->next && p < q->next)
  69.      break;        /* new block goes at beginning of list */
  70.    }
  71.  
  72.    if ((struct header *) ((char *) p + p->size) == q->next) {
  73.       p->size += q->next->size;
  74.       p->next = q->next->next;
  75.    } else {
  76.       p->next = q->next;
  77.    }
  78.    if ((struct header *) ((char *) q + q->size) == p) {
  79.       q->size += p->size;
  80.       q->next = p->next;
  81.    } else {
  82.       q->next = p;
  83.    }
  84.    head = q;
  85. }
  86.  
  87.  
  88. /* getmem - request more memory from system */
  89.  
  90. struct header *getmem ()
  91. {
  92.    char *AllocMem ();
  93.    register struct header *up;
  94.  
  95.    if ((up = (struct header *) AllocMem (HOWMUCH, 0L)) == NULL)
  96.       return (NULL);    /* can't get more memory */
  97.    up->next = NULL;
  98.    up->size = HOWMUCH;
  99.    freeit ((char *) (up + 1));
  100.    return (head);
  101. }
  102.  
  103.  
  104. quit (code)
  105. int code;
  106. {
  107.    register struct header *p, *q;
  108.    unsigned long size;
  109.  
  110.    p = head;
  111.    do {
  112.       if (p == NULL)
  113.          break;
  114.       q = p->next;
  115.       if ((size = p->size) > 0L) {
  116.      p->size = 0L;
  117.          FreeMem (p, size);
  118.       }
  119.       p = q;
  120.    } while (p != head);
  121.    exit (code);
  122. }
  123.